﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using Apache.NMS.ActiveMQ.Commands;
using System.Windows.Controls;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Windows;

namespace ModeloGaleriaNET
{
    delegate void SetTextIntoPanel();
    public class Utilities
    {
        /// <summary>
        /// Clave del algoritmo RSA empleado para encriptar la contraseña
        /// </summary>
        private static String CLAVE = "<RSAKeyValue><Modulus>1L+sSEtl3cNwEHUmE25/4qsKQ6BqQhYoGjaQ/ebdZR8vBMAL1LVb4C0pbMaY0GSkU9iY5H3O1lccejiWWFHnzNtLBYdt7vj0N8W1DnpV9LG3ShY5YjacldW6XR1zTBMgNq42jNxwIT+6nNGvfoM/DgNMUCtPDblU9+VZYkynLps=</Modulus><Exponent>AQAB</Exponent><P>/B1OBrbfSngKVgr59IE1EdSm6lc1Dh9R/9w4e8GPnbhq/DCvpvt7ULBSHdocStyjSH1WCUhLh4Qi/wwZJO8+Gw==</P><Q>2AcN21YxRw04RJDZfhZVbUAzZStEXyNe4T2G4/twv182IWFly3+aRUfs27St2IMfyQkGRkl1bgODXq7K5JzZgQ==</Q><DP>E9C91DtFW5YJwe+E69nH8QnUwLBwBBckG8cUTW3OOuhGyGGPPMGhVJs3KQ9+j8e9sbHgNESRYypYkdFCnKuNJw==</DP><DQ>fYMTtPUOKmbu4z95bf2R4qjjc4tA7TnCvYEe50TGjBnIfHp3R1W7Dzer0TbXrqz4gbghkiLJ/IJECHXr4gmTgQ==</DQ><InverseQ>oYxAxz6Va599X4IrMWFIc6Au+cTjnS8v4D2SnSDyxlOSkTB3trGIgSH7KhdyIIrUJxYrwuoBOg90eUm2dilKsA==</InverseQ><D>OS3i0fNhx36VifbSavqR6Ivr0E03AdgOoyzzPypjaqA89Nvg0iSEMvYwYgnmXGwQNnDKdu7RPo5fGwJGdipdUBX18DaAmIXYLpCM0W69YLGHMt+HnX0wafbNjFfGvQaJvBkJ+wZBVAcmNC64a4Iw82WTvHzcndsqPbVjha/nggE=</D></RSAKeyValue>";

        public static void WriteMessageOnGrid(AvalonDock.DockableContent doc, string message, DataGridMessage.TIPO_MENSAJE t)
        {
            doc.Dispatcher.Invoke((SetTextIntoPanel)delegate()
            {
                DataGridMessage mensaje = new DataGridMessage(DateTime.Now, message, t);
                mensaje.Contenido = null;
                ((DataGrid)doc.Content).Items.Add(mensaje);
                ((DataGrid)doc.Content).ScrollIntoView(((DataGrid)doc.Content).Items[((DataGrid)doc.Content).Items.Count - 1]);
            });
        }

        public static void WriteMessageOnGrid(AvalonDock.DockableContent doc, string message, DataGridMessage.TIPO_MENSAJE t, ActiveMQMapMessage mapMessage)
        {
            doc.Dispatcher.Invoke((SetTextIntoPanel)delegate()
            {
                DataGridMessage mensaje = new DataGridMessage(DateTime.Now, message, t);
                mensaje.Contenido = ((ActiveMQMapMessage)mapMessage);
                ((DataGrid)doc.Content).Items.Add(mensaje);
                ((DataGrid)doc.Content).ScrollIntoView(((DataGrid)doc.Content).Items[((DataGrid)doc.Content).Items.Count - 1]);
            });
        }

        public static string EncriptarSHA1(string s)
        {
            SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
            byte[] bytes = null;
            StringBuilder sb;

            sb = new StringBuilder();
            bytes = sha.ComputeHash(Encoding.Default.GetBytes(s));

            for (int i = 0; i < bytes.Length; i++)
                sb.Append(bytes[i].ToString("x2"));

            return sb.ToString();
        }

        public static string EncriptarMD5(string s)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] bytes = null;
            StringBuilder sb;

            sb = new StringBuilder();
            bytes = md5.ComputeHash(Encoding.Default.GetBytes(s));

            for (int i = 0; i < bytes.Length; i++)
                sb.Append(bytes[i].ToString("x2"));

            return sb.ToString();
        }

        public static string EncriptarRSA(string s)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(CLAVE);
            return string.IsNullOrWhiteSpace(s) ? string.Empty
                   : Encoding.Default.GetString(rsa.Encrypt(Encoding.Default.GetBytes(s), false));
        }

        public static string DesencriptarRSA(string s)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(CLAVE);
            return string.IsNullOrWhiteSpace(s) ? string.Empty : 
                Encoding.Default.GetString(rsa.Decrypt(Encoding.Default.GetBytes(s), false));
        }

        public static int GetZonaHoraria()
        {
            TimeZoneInfo tziLocal;
            ZonaHoraria zona = null;
            List<ZonaHoraria> zonas;
            List<ZonaHoraria> zonasAux;
            List<TimeZoneInfo> locales;
            TimeSpan offset;
            List<TimeZoneInfo> timeZones;

            offset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);
            timeZones = TimeZoneInfo.GetSystemTimeZones().Where(tz => tz.GetUtcOffset(DateTime.Now).Equals(offset)).ToList();
            tziLocal = TimeZoneInfo.Local;
            locales = timeZones.Where(tz => tz.DisplayName.Equals(tziLocal.DisplayName)).ToList();

            try
            {
                zonas = GaleriaContext.Instance.Contexto.ZonasHorarias.ToList();
            }
            catch (Exception)
            {
                System.Threading.Thread.Sleep(1000);
                zonas = GaleriaContext.Instance.Contexto.ZonasHorarias.ToList();
            }

            if (locales != null && locales.Count > 0)
                zona = zonas.Where(zh => zh.StandardName.Equals(locales.First().Id)).First();
            else
            {
                // Iterate time zones 
                foreach (TimeZoneInfo timeZone in timeZones)
                {
                    zonasAux = zonas.Where(zh => zh.StandardName.Equals(timeZone.Id)).ToList();
                    if (zonasAux != null && zonasAux.Count > 0)
                    {
                        zona = zonasAux.First();
                        break;
                    }
                }
            }

            return zona.Id;
        }

        public static string ListToString(List<string> lista, string separador)
        {
            string salida;

            salida = string.Empty;
            foreach (string s in lista)
            {
                if (string.IsNullOrWhiteSpace(salida))
                    salida = s;
                else
                    salida += separador + s;
            }

            return salida;
        }

        public static string ArrayToString(string[] array, string separador)
        {
            return ListToString(array.ToList(), separador);
        }

        public static string GetLocalIP()
        {
            try
            {
                IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());

                foreach (IPAddress ip in localIPs)
                {
                    if (ip.AddressFamily == AddressFamily.InterNetwork)
                        return ip.ToString();
                }
                return "IP not found";
            }
            catch (Exception)
            {
                return "IP not found";
            }
        }

        public static object FindUsuarioData(Type userWindowType, UserControl control, string field)
        {
            DependencyObject padre;
            Usuario user = null;

            try
            {
                padre = control.Parent;
                if (padre is AvalonDock.DocumentContent)
                {
                    padre = ((AvalonDock.DocumentContent)padre).Manager;
                    if (padre is AvalonDock.DockingManager)
                    {
                        padre = ((AvalonDock.DockingManager)padre).Parent;
                        if (padre is Grid)
                        {
                            padre = ((Grid)padre).Parent;
                            if (padre.GetType().Equals(userWindowType))
                            {
                                user = (Usuario)userWindowType.GetProperty("Usuario", typeof(Usuario)).GetValue(padre, null);
                                if (field.Equals("Id"))
                                    return user.Id;
                                else if (field.Equals("Name"))
                                    return user.PseudonimoLocal;
                                else
                                    return null;
                            }
                            else
                                throw new ErrorOpeningNewDocumentException("No se puede abrir la nueva ventana");
                        }
                        else
                            throw new ErrorOpeningNewDocumentException("No se puede abrir la nueva ventana");
                    }
                    else
                        throw new ErrorOpeningNewDocumentException("No se puede abrir la nueva ventana");
                }
                else
                    throw new ErrorOpeningNewDocumentException("No se puede abrir la nueva ventana");
            }
            catch (ErrorOpeningNewDocumentException)
            {
                return null;
            }
        }
    }
}
